#include "dbms_channel.h"
#include <chrono>
#include <sstream>
#include <string.h>
#include "dbms.pb.h"

namespace dbms {
DbmsChannel::DbmsChannel(const std::string &dbFile)
	: Dbms<DeviceChannel_t>(dbFile, "channel")
{
	// cteate table if not exist
	CreateTable("channel");
}
void DbmsChannel::Save(const DeviceChannel_t &dc)
{
	const std::string id = FindEqual(dc,
		[](const dbms::DeviceChannel_t &t1,
			const dbms::DeviceChannel_t &t2) -> bool {
			if (t1.ctype() != t2.ctype()) {
				return false;
			}
			if (t1.ctype() == dbms::CT_COM) {
				return t1.com().name() == t2.com().name();
			} else if (t1.ctype() == dbms::CT_TCP ||
					   t1.ctype() == dbms::CT_UDP) {
				return (t1.socket().ip() == t2.socket().ip()) &&
					   (t1.socket().port() == t2.socket().port());
			}
			return false;
		});
	if (id != "") {
		Update(id, dc);
	} else {
		auto now = std::chrono::system_clock::now();
		auto curTime = std::chrono::system_clock::to_time_t(now);
		std::ostringstream oss;
		oss << curTime;
		Insert(oss.str(), dc);
	}
}

void DbmsChannel::Get(
	std::function<void(const dbms::DeviceChannel_t &dc)> onGet)
{
	GetAll(onGet);
}

std::vector<DeviceChannel_t> DbmsChannel::Get()
{
	std::vector<DeviceChannel_t> listDc;
	GetAll(
		[&listDc](const dbms::DeviceChannel_t &dc) { listDc.push_back(dc); });
	return listDc;
}

std::string DbmsChannel::Serialize(const DeviceChannel_t &t)
{
	return t.SerializeAsString();
}

DeviceChannel_t DbmsChannel::Deserialize(const std::string &data)
{
	DeviceChannel_t t;
	t.ParseFromString(data);
	return t;
}
} // namespace dbms